package com.umfwechat.wx.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.umfwechat.common.constant.CacheConsts;
import com.umfwechat.common.constant.PropertyConsts;
import com.umfwechat.util.PropertyUtil;
import com.umfwechat.util.RedisUtil;
import com.umfwechat.util.WexinQrCodeUtil;
import com.umfwechat.util.wx.WeixinHttpClientUtils;
import com.umfwechat.util.wx.WeixinUtil;
import com.umfwechat.wx.service.WeixinService;
import com.umpay.operation.util.StringUtil;

/**
 * GET测试 http://127.0.0.1:8080/umfWeChatPlat/messagePush/test
 * 公众号与小程序消息推送公共类（供运营平台使用）http://127.0.0.1:8080/umfWeChatPlat/messagePush/send
 * 获取公众号收款人邀请二维码（供运营平台使用）http://127.0.0.1:8080/umfWeChatPlat/messagePush/payeeQrCode
 * 获取公众号收款人邀请二维码Url列表（供自服务平台使用）http://127.0.0.1:8080/umfWeChatPlat/messagePush/payeeTicketUrlList
 * 
 * @author ChenFuLong
 */
@Controller
@RequestMapping("/messagePush")
public class MessagePushController {
	
	private static Logger logger = LoggerFactory.getLogger(MessagePushController.class);
	private static String APPID1 = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties").getProperty("saas.wx.appid");// 微信公众号appid
	private static String APPSECRET1 = PropertyUtil.getProperties("umfWeChatPlat_appConf.properties").getProperty("saas.wx.appsecret");// 微信公众号appsecret

	@Autowired
	private WeixinService weixinService;
	
/*============================================== 公众号与小程序消息推送公共类（供运营平台使用） ==============================================*/

	/**
	 * GET请求
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	@RequestMapping(value = "/test", method = { RequestMethod.GET })
	public void test(HttpServletRequest request, HttpServletResponse response) throws IOException{
		request.setCharacterEncoding("UTF-8");  
	    response.setContentType("text/html");  
	    response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		try {
			out.print("接口启动成功");
		} catch (Exception e) {
			out.print(e);
		}finally{
			if (out != null) {
				out.flush();
                out.close();
			}
		}
	}
	
	/**
	 * 消息推送
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/send", method = { RequestMethod.POST })
	public void messagePush(HttpServletRequest request, HttpServletResponse response){
		try {
			String str = readFromIO(request.getInputStream(), "UTF-8");
			JSONObject json = JSONObject.fromObject(str);
			String type = (String) json.get("type");	//消息推送类型：1公众号；2小程序
			String param = json.getString("param");	//要推送的消息（微信文档）
			if (type.equals("1")) {
				weChat(param);
			}
			if (type.equals("2")) {
				applet(param);
			}
		} catch (Exception e) {
			logger.error("【推送消息】异常",e);
		}
	}
	
	/**
	 * 推送公众号消息
	 */
	public void weChat(String param){
		logger.info("【开始推送公众号消息】" + param);
		String accessToken = RedisUtil.get(CacheConsts.WX + "access");	//从redis中获取accessToken
		if (StringUtils.isBlank(accessToken)) {
			accessToken = WeixinUtil.getAccessToken(APPID1, APPSECRET1).getAccessToken();
			RedisUtil.set(CacheConsts.WX + "access", 1800, accessToken);
			long time = new Date().getTime();
			String of = String.valueOf(time);
			RedisUtil.set(CacheConsts.WX + "accesstime",2000,of);
		}
		logger.info("【获取accessToken】" + accessToken);
		String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
		logger.info("【推送公众号消息】请求参数：" + param);
		JSONObject json = WeixinHttpClientUtils.httpRequest(url, "POST", param);
		logger.info("【推送公众号消息】返回参数：" + json);
	}
	
	/**
	 * 推送小程序消息
	 */
	@SuppressWarnings("static-access")
	public void applet(String param){
		logger.info("【开始推送小程序消息】" + param);
		String accessToken = RedisUtil.get("XCX_ACCESS_TOKEN");	//从redis中获取accessToken
		if (StringUtils.isBlank(accessToken)) {
			WexinQrCodeUtil wexinQrCodeUtil = new WexinQrCodeUtil();
			accessToken = wexinQrCodeUtil.reqToken();
			RedisUtil.set("XCX_ACCESS_TOKEN", 3600, accessToken);
		}
		JSONObject str = JSONObject.fromObject(accessToken);
		String token = (String) str.get("access_token");
		logger.info("【获取accessToken】" + token);
		String url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" + token;
		logger.info("【推送小程序消息】请求参数：" + param);
		JSONObject json = WeixinHttpClientUtils.httpRequest(url, "POST", param);
		logger.info("【推送小程序消息】返回参数：" + json);
	}
	
/*============================================== 获取公众号收款人邀请二维码（供运营平台使用） ==============================================*/
	
	/**
	 * 获取公众号收款人邀请二维码
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	@RequestMapping(value = "/payeeQrCode", method = { RequestMethod.POST })
	public void payeeQrCode(HttpServletRequest request, HttpServletResponse response) throws IOException{
		PrintWriter out = response.getWriter();
		try {
			String str = readFromIO(request.getInputStream(), "UTF-8");
			JSONObject json = JSONObject.fromObject(str);
			String userId = json.getString("userId");	//获取收款人userId
			logger.info("【运营平台获取收款人邀请码】" + userId);
			String expireTime="86400";//24小时
			Integer scene_id=Integer.valueOf(userId);
			String qrCodeUrl = weixinService.getTicketQrCode(expireTime,scene_id);
			out.print("{\"retCode\":\"0000\",\"qrCodeUrl\":\""+qrCodeUrl+"\"}");
		} catch (Exception e) {
			logger.error("【运营平台获取收款人邀请码】异常",e);
			out.print("{\"retCode\":\"0001\",\"qrCodeUrl\":\"\"}");
		}finally{
			if (out != null) {
				out.flush();
                out.close();
			}
		}
	}
	
	/**
	 * 获取公众号收款人邀请二维码Url列表
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	@RequestMapping(value = "/payeeTicketUrlList", method = { RequestMethod.POST })
	public void payeeTicketUrlList(HttpServletRequest request, HttpServletResponse response) throws IOException{
		PrintWriter out = response.getWriter();
		try {
			String requestStr = readFromIO(request.getInputStream(), "UTF-8");
			Map<String, String> paramMap = new Gson().fromJson(requestStr, new TypeToken<Map<String, String>>(){}.getType());
			Map<String, String> resultMap = new HashMap<String, String>();
			String ticketUrlKey = CacheConsts.SAASWXTICKETURL;
			for(String storeIdKey : paramMap.keySet()){
				//获取收款人userId
				String userId = paramMap.get(storeIdKey);
				logger.info("【自服务平台获取收款人邀请码】userId=" + userId);
				//查缓存
				String ticketUrl = RedisUtil.get(ticketUrlKey + userId);
				if(StringUtil.isEmpty(ticketUrl)){
					//有效期30天
					String oneMonth = String.valueOf(PropertyConsts.ONEMONTH);
					//生成ticketUrl
					ticketUrl = weixinService.getTicketUrl(oneMonth, Integer.valueOf(userId));
					//缓存1天
					RedisUtil.set(ticketUrlKey + userId, PropertyConsts.ONEDAY, ticketUrl);
				}
				resultMap.put(storeIdKey, ticketUrl);
			}
			String resultStr = JSONObject.fromObject(resultMap).toString();
			logger.info("【自服务平台获取收款人邀请码】返回数据：" + resultStr); 
			out.print(resultStr);
			
		} catch (Exception e) {
			logger.error("【自服务平台获取收款人邀请码Url】异常",e);
			out.print("{\"retCode\":\"0001\",\"resultStr\":\"\"}");
		}finally{
			if (out != null) {
				out.flush();
                out.close();
			}
		}
	}
	
	
/*============================================== 公共方法 ==============================================*/	
	
	/**
	 * 获取请求信息
	 * @param is
	 * @param encoding
	 * @return
	 * @throws IOException
	 */
	public String readFromIO(InputStream is, String encoding) throws IOException{
		StringBuffer xml = new StringBuffer();
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(is, encoding));
			String s = null;
			while ((s = br.readLine()) != null) {
				xml.append(s);
			}
		} finally {
			if (br != null) {
				try {
					br.close();
					br = null;
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		logger.info("【第三方请求报文】" + xml.toString());
		return xml.toString();
	}
	
}